package com.xx.doublexchat.common.user.service.impl;

import com.xx.doublexchat.common.common.annotation.RedissonLock;
import com.xx.doublexchat.common.common.domain.enums.YesOrNoEnum;
import com.xx.doublexchat.common.common.service.LockService;
import com.xx.doublexchat.common.common.utils.AssertUtils;
import com.xx.doublexchat.common.user.dao.UserBackpackDao;
import com.xx.doublexchat.common.user.domain.entity.UserBackpack;
import com.xx.doublexchat.common.user.domain.enums.IdempotentEnum;
import com.xx.doublexchat.common.user.service.IUserBackpackService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

@Service
public class UserBackpackServiceImpl implements IUserBackpackService {

   /* @Autowired
    private RedissonClient redissonClient;*/

    @Autowired
    private LockService lockService;

    @Autowired
    private UserBackpackDao userBackpackDao;

    /**
     * 用户方法物品
     * @param uid 用户id
     * @param itemId 物品id
     * @param idempotentEnum 幂等类型
     * @param businessId 幂等唯一标识
     */
    @Override
    public void acquireItem(Long uid, Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        String idempotent = getIdempotent(itemId, idempotentEnum, businessId);
        // 使用动态代理保证事务生效
        UserBackpackServiceImpl userBackpackService = (UserBackpackServiceImpl) AopContext.currentProxy();
        userBackpackService.doAcquireItem(uid, itemId, idempotent);
    }
    @Transactional
    @RedissonLock(key = "#idempotent", waitTime = 5000)
    public void doAcquireItem(Long uid, Long itemId, String idempotent) {
        UserBackpack userBackpack = userBackpackDao.getByIdempotent(idempotent);
        // 幂等存在不进行后续逻辑
        if (Objects.nonNull(userBackpack)) {
            return;
        }
        // 业务检查(自定义逻辑)

        // 发放物品
        UserBackpack insert = UserBackpack.builder()
                .uid(uid)
                .itemId(itemId)
                .status(YesOrNoEnum.NO.getStatus())
                .idempotent(idempotent)
                .build();
        userBackpackDao.save(insert);
    }

    /**
     * 获取幂等信息
     * @param itemId
     * @param idempotentEnum
     * @param businessId
     */
    private String getIdempotent(Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        return String.format("%d_%d_%s",itemId,idempotentEnum.getType(),businessId);
    }
}
